/**
*  Creates a semaphore for exclusive access
*
* Project: idbCrownInServer
* Author:  TM
* Date:    01/03/2013
*
* History
* ------------------
* 01/03/2013 - TM - Initial version.
*/
 
package DataModel;

import Application.*;

public class libSemaphore
{
  /** Number of times semaphore has been requested for current thread */
  protected int count;
  /** Thread to which semaphore belongs */
  protected Thread thread;
  /** Application support */
  protected libApplication appSupport;
  

  /** Constructor */
  public libSemaphore()
  {
    count      = 0;
    thread     = null;
    appSupport = libApplication.getInstance();
  }

  /** Request semaphore for current thread (if thread is currently locking it, count request up) -
      wait if semaphore not available
    */
  public synchronized int up() throws InterruptedException
  {
    while (thread != Thread.currentThread() && thread != null)
      wait();   // When it awakes, back to check no other (faster) waiting thread already caught it

    thread = Thread.currentThread();
    count++;
    return count;
  }

  /** Release semaphore when request count gets down to zero - not allowed to go below zero */
  public synchronized int down()
  {
    //Checks
    if (Thread.currentThread() != thread)
    {
       appSupport.showErrorMsg(libExceptionConst.INVALID_METHOD_CALL);
       return -1;
    }

    if (--count <= 0)
    {
      thread = null;
      notify();
      count = 0;  // Don't allow to go below zero
    }
    return count;
  }

  /** Number of times semaphore has been requested for current thread - returns -1 if not current thread */
  public synchronized int getUpCount()
  {
    return thread == null || Thread.currentThread() == thread ? count : -1;
  }
}
